/**
* Copyright© 2025 CQUPT( Compact Quick Unified Protocol for Transfer) Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cqupt.h"

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
/**
 * 计算校验和
 * @param data 指向数据的指针
 * @param length 数据的长度
 * @return 校验和
 */
uint32_t cqupt_calculate_checksum(const void* data, size_t length) {
    if (data == NULL || length == 0) {
        return 0; // 返回0表示无效数据
    }
    uint32_t checksum = 0;
    const uint8_t* byte_data = (const uint8_t*)data;
    for (size_t i = 0; i < length; i++) {
        checksum += byte_data[i];
    }
    return checksum;
}
/**
 * @brief 检验CQUPT请求头的有效性，包括版本号、长度和类型等。
 * @details 1. 检验参数是否为NULL 2. 检验版本号是否匹配 3. 检验长度是否为正数 4. 检验类型是否为上传或下载
 * @note 目前未实现校验和的校验，后续可以添加
 * @param header 指向CQUPT请求头的指针
 * @return 校验结果, 0代表有效
 */
int cqupt_validate_header(const cqupt_header_t* header) {
    if (header == NULL) {
        return CQUPT_ERROR_INVALID_HEADER;
    }
    if (header->version != CQUPT_VERSION) {
        return CQUPT_ERROR_INVALID_VERSION;
    }
    if (header->length < 0) {
        return CQUPT_ERROR_INVALID_LENGTH;
    }
    switch (header->type) {
        case CQUPT_ACK_SUCCESS:
        case CQUPT_CMD_UPLOAD:
        case CQUPT_CMD_UPLOAD_END:
        case CQUPT_CMD_DOWNLOAD:
        case CQUPT_CMD_DOWNLOAD_END:
        case CQUPT_ACK_FAILURE:
            break;
        default:
            return CQUPT_ERROR_UNSUPPORTED_TYPE;
    }
    return 0;
}

/**
 * 响应请求头
 * @param sockfd socket连接
 * @param buffer 接收缓存区
 * @return 请求的类型
 */
int cqupt_receive_response(int sockfd, char *buffer) {
    cqupt_header_t header;
    if (recv(sockfd, (char *)&header,sizeof(header),0)<=0) {
        fprintf(stderr,"receive fail");
        return -1;
    }
    if (cqupt_validate_header(&header)!=0) {
        return CQUPT_ERROR_INVALID_HEADER;
    }
    if (recv(sockfd, buffer,header.length,0)<=0) {
        fprintf(stderr, "header response fail");
        return -1;
    }
    buffer[header.length]='\0';

    return header.type;
}

